<template>
  <div h-31px v-if="!enableEdit" cursor-move my-5px flex flex-a-c flex-j-sb bg-gray-100 p-6px rounded hover:bg-gray-300
    :ref="setRef" class="card" :style="{ opacity }" :data-handler-id="handlerId">
    <div v-auto-animate>
      <div flex flex-a-c>
        <div mr-5px><icon-drag-arrow class="no-border" color-gray /></div>
        <div text-13px>{{ res.name }}</div>
      </div>
    </div>
    <div>
      <icon-edit mr-2px @click="editModelName" />
      <a-popconfirm content="是否删除该组件?" @ok="deleteModel">
        <icon-delete />
      </a-popconfirm>

    </div>
  </div>
  <div v-else>
    <a-input show-word-limit @keyup.enter="handleBlur" v-model="res.name" :max-length="6">
      <template #append>
        <icon-check @click="handleDone" />
      </template>
    </a-input>
  </div>
</template>
<script lang="ts" setup>
import { computed, ref, unref, } from 'vue'
import { useDrag, useDrop } from 'vue3-dnd'
import { DragRule } from '@/views/operation/decoration/app/models/types';
import { toRefs } from '@vueuse/core'
import { useDesign } from '@/store'

const enableEdit = ref<boolean>(false)
const userDesign = useDesign();
const props = defineProps<{
  id: any
  text: string
  index: number
  res: DragRule
  moveCard: (dragIndex: number, hoverIndex: number) => void
}>()
const emit = defineEmits(['update', 'delete'])

function handleDone() {
  enableEdit.value = false
}

// 删除组件
function deleteModel() {
  emit('delete', { data: props.res, index: props.index })
}

// 点击事件
function handleBlur() {
  enableEdit.value = false
}
// 修改组件名称
function editModelName() {
  enableEdit.value = true
  emit('update', { data: props.res, index: props.index })
}
const card = ref<any>('')
const [dropCollect, drop] = useDrop({
  accept: 'mini-map',
  collect(monitor) {
    return {
      handlerId: monitor.getHandlerId(),
    }
  },
  hover(item: any, monitor) {
    if (!card.value) {
      return
    }
    const dragIndex = item.index
    const hoverIndex = props.index
    // Don't replace items with themselves
    if (dragIndex === hoverIndex) {
      return
    }

    // Determine rectangle on screen
    const hoverBoundingRect = card.value?.getBoundingClientRect()

    // Get vertical middle
    const hoverMiddleY = (hoverBoundingRect.bottom - hoverBoundingRect.top) / 2

    // Determine mouse position
    const clientOffset: any = monitor.getClientOffset()

    // Get pixels to the top
    const hoverClientY = (clientOffset).y - hoverBoundingRect.top

    // Only perform the move when the mouse has crossed half of the items height
    // When dragging downwards, only move when the cursor is below 50%
    // When dragging upwards, only move when the cursor is above 50%

    // Dragging downwards
    if (dragIndex < hoverIndex && hoverClientY < hoverMiddleY) {
      return
    }

    // Dragging upwards
    if (dragIndex > hoverIndex && hoverClientY > hoverMiddleY) {
      return
    }

    // Time to actually perform the action
    props.moveCard(dragIndex, hoverIndex)

    // Note: we're mutating the monitor item here!
    // Generally it's better to avoid mutations,
    // but it's good here for the sake of performance
    // to avoid expensive index searches.
    item.index = hoverIndex
  },
})

const [collect, drag] = useDrag({
  type: 'mini-map',
  item: () => {
    userDesign.setAppActiveIndex(props.index);
    return { id: props.id, index: props.index }
  },
  collect: (monitor: any) => ({
    isDragging: monitor.isDragging(),
  }),
})

const { handlerId } = toRefs(dropCollect)
const { isDragging } = toRefs(collect)
const opacity = computed(() => (unref(isDragging) ? 0 : 1))

const setRef: any = (el: HTMLDivElement) => {
  card.value = drag(drop(el)) as HTMLDivElement
}
</script>



<style lang="less" scoped>
</style>
